package com.qianwen.wallpaper;

import android.app.Service;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.WindowManager;

import androidx.annotation.Nullable;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Optional;
import java.util.Random;

/**
 * 壁纸切换服务
 *
 * @author qianwen
 * @since 2021/7/24
 */
public class MyWallPaperService extends Service {
    private static final String TAG = MyWallPaperService.class.getSimpleName();

    private static final Handler HANDLER = new Handler(Looper.getMainLooper());

    private static final Random RANDOM = new Random();

    private static final long DELAY = 3600 * 1000L;

    private static final long QUICK_CLICK_DELAY = 500L;

    private WallpaperManager wallpaperManager;

    private Double DISPLAY_RAT = 0D;

    public boolean SWITCH_SYSTEM = false;

    private final Runnable runnable = () -> {
        switchWallpaper(MyWallPaperService.this);
        long delay = ConfigCache.getDuration(MyWallPaperService.this) * DELAY;
        HANDLER.postDelayed(MyWallPaperService.this.runnable, delay);
    };


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        wallpaperManager = WallpaperManager.getInstance(this);
        getDisplayRat();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String type = intent.getStringExtra("type");
        SWITCH_SYSTEM = type != null;
        if (HANDLER.hasCallbacks(runnable)) {
            HANDLER.removeCallbacks(runnable);
        }
        HANDLER.postDelayed(runnable, QUICK_CLICK_DELAY);
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 获取屏幕比例
     */
    private void getDisplayRat() {
        if (DISPLAY_RAT == 0) {
            DISPLAY_RAT = Optional.ofNullable(getBaseContext())
                    .map(context -> context.getSystemService(Context.WINDOW_SERVICE))
                    .map(serivce -> (WindowManager) serivce)
                    .map(WindowManager::getDefaultDisplay)
                    .map(display -> (double) display.getHeight() / (double) display.getWidth())
                    .orElse(0D);
        }
    }

    /**
     * 是否竖屏
     *
     * @return boolean
     */
    private boolean isScreenOrientation(Context context) {
        return Optional.ofNullable(context)
                .map(Context::getResources)
                .map(Resources::getConfiguration)
                .map(configuration -> configuration.orientation == Configuration.ORIENTATION_PORTRAIT)
                .orElse(false);
    }

    /**
     * 切换壁纸
     *
     * @param context 上下文
     */
    private void switchWallpaper(Context context) {
        if (!isScreenOrientation(context)) {
            return;
        }
        long start = System.currentTimeMillis();
        Log.i(TAG, "switch wallpaper");
        File file = new File(ConfigCache.BASE_PATH + ConfigCache.getPath(this));
        Optional.ofNullable(file.listFiles()).ifPresent(files -> {
            File pic = files[RANDOM.nextInt(files.length)];
            Log.i(TAG, pic.getAbsolutePath());  
            try (InputStream inputStream = Files.newInputStream(pic.toPath())) {
                boolean isDeskSwitch = ConfigCache.getDeskSwitch(this);
                boolean isLockSwitch = ConfigCache.getLockSwitch(this);
                if (isDeskSwitch && !isLockSwitch) {
                    setDeskWallpaper(inputStream);
                    return;
                }
                if (!isDeskSwitch && isLockSwitch) {
                    setLockWallpaper(inputStream, pic);
                    return;
                }
                if (SWITCH_SYSTEM) {
                    setDeskWallpaper(inputStream);
                } else {
                    setLockWallpaper(inputStream, pic);
                }
                SWITCH_SYSTEM = !SWITCH_SYSTEM;
            } catch (IOException e) {
                Log.i(TAG, "ioexception : " + e.getCause());
            }
        });
        long end = System.currentTimeMillis();
        Log.i(TAG, "switch wallpaper cost : " + (end - start));
    }

    /**
     * 设置桌面壁纸
     *
     * @param inputStream 壁纸文件流
     * @throws IOException IO异常
     */
    private void setDeskWallpaper(InputStream inputStream) throws IOException {
        wallpaperManager.setStream(inputStream, null, false, WallpaperManager.FLAG_SYSTEM);
    }

    /**
     * 设置锁屏壁纸
     *
     * @param inputStream 壁纸文件流
     * @param pic         壁纸文件
     * @throws IOException IO异常
     */
    private void setLockWallpaper(InputStream inputStream, File pic) throws IOException {
        Bitmap bitmap = BitmapFactory.decodeFile(pic.getAbsolutePath());
        int height = bitmap.getHeight();
        int width = bitmap.getWidth();
        bitmap.recycle();
        Rect rect;
        if (DISPLAY_RAT * width > height) {
            //过宽
            int actWidth = Double.valueOf(height / DISPLAY_RAT).intValue();
            rect = new Rect((width - actWidth) / 2, 0, actWidth, height);
        } else {
            //过高
            int actHeight = Double.valueOf(width * DISPLAY_RAT).intValue();
            rect = new Rect(0, (height - actHeight) / 2, width, actHeight);
        }
        wallpaperManager.setStream(inputStream, rect, true, WallpaperManager.FLAG_LOCK);
    }
}
